﻿
using System ;
using System.Diagnostics ;

using MskEdit.Sdk ;
using MskEdit.Msk.Representation ;


namespace MskEdit.Msk.Model
{    
    public class MskPageCode
    {  

#region Private data

        private static  MskPageCode nullPageCode_ = new MskPageCode() ;
        private         int         PageCode_ ;
           
#endregion

#region Private validations

        private static bool FindsValidPageCodeIn( int code ) {
            return ( code >= 1 ) && ( code <= 128 ) && ( SdkBitAlgoritms.BitCount( code ) == 1 ) ;
        }
        
        private static bool FindsValidPageNumberIn( int number ) {
            return ( number >= 1 ) && ( number <= 8 ) ;
        }

        private static int CodeToNumber( int code ) {
            int number = SdkBitAlgoritms.BitLsbPos( code ) ;
            return number ;
        }
        
        private static int NumberToCode( int number ) {
            int code = 1 << ( number - 1 ) ;
            return code ;
        }

#endregion

#region Private foundation

        private MskPageCode() {
            PageCode_ = 0 ;
        }
        
        private MskPageCode( int pageCode ) {
            PageCode_ = pageCode ;
        }


#endregion

#region Public foundation

        public override bool Equals( object obj ) {
        
            MskPageCode that = ( MskPageCode ) obj ;
            if ( that.PageCode_ != this.PageCode_ )
                return false ;
                
            return true ;
        }


        public override int GetHashCode() {
            return PageCode_ ;
        }
        

        public override String ToString() {
            return Number.ToString() + "( " + Code.ToString() + " )" ;
        }


#endregion
 
#region Public parsers

        static public MskPageCode TryFrom( int pageCode, MskPageCode fallbackValue ) {
                        
            if ( ! MskPageCode.FindsValidPageCodeIn( pageCode ) )
                return fallbackValue ;
                
            return new MskPageCode( pageCode ) ;
        }


        static public MskPageCode TryParseFrom( string pageCodeAsString, MskPageCode fallbackValue ) {
        
            int pageCode ;
            if ( ! int.TryParse( pageCodeAsString, out pageCode ) )
                return fallbackValue ;
                
            return TryFrom( pageCode, fallbackValue ) ;
        }


        static public MskPageCode TryFrom( string line, MskPageCode fallbackValue ) {
        
            int? code = IntField.PageCode.TryFrom( line, null ) ;
            if ( ! code.HasValue )
                return fallbackValue ;
                
            return new MskPageCode( code.Value ) ;
        }


        public bool Matches( string line ) {
        
            int? pageCode = IntField.PageCode.TryFrom( line, null ) ;
            if ( ! pageCode.HasValue )
                return false ;
                
            if ( PageCode_ != pageCode.Value )
                return false ;
                
            return true ;
        }
        
#endregion

#region Public properties

        public static MskPageCode NullPageCode {
            get { return nullPageCode_ ; }
        }


        public int Code {
            get { return PageCode_ ; }
        }


        public int Number {
            get { return SdkBitAlgoritms.BitLsbPos( PageCode_ ) ; }
        }

#endregion
 
    }
}
